<template>
  <div>
    <editor :id="id" :init="rootConfig" v-model="tinymceHtml"></editor>
  </div>
</template>
<script>
  import tinymce from 'tinymce/tinymce'
  import 'tinymce/themes/modern/theme'
  import Editor from '@tinymce/tinymce-vue'
  import 'tinymce/plugins/image'
  import 'tinymce/plugins/link'
  import 'tinymce/plugins/code'
  import 'tinymce/plugins/table'
  import 'tinymce/plugins/lists'
  import 'tinymce/plugins/contextmenu'
  import 'tinymce/plugins/wordcount'
  import 'tinymce/plugins/colorpicker'
  import 'tinymce/plugins/textcolor'
  import 'tinymce/plugins/imagetools'
  import 'tinymce/plugins/fullscreen'
  import 'tinymce/plugins/importcss'
  import 'tinymce/plugins/advlist'
  import 'tinymce/plugins/media'
  import 'tinymce/plugins/hr'
  import 'tinymce/plugins/preview'
  import 'tinymce/plugins/paste'
  /**
   * $emit
   *  on-ready：实例加载完成执行的回调
   *  input：输入内容时执行的回调
   *  on-destroy：实例销毁时执行的回调
   *  on-upload-success：图片上传成功时的回调
   *  on-upload-fail：图片上传失败时的回调
   * */
  export default {
    name: 'tinymce-editor',
    data () {
      return {
        // 富文本的值
        tinymceHtml: '',
        // 默认配置
        DefaultConfig: {
          // GLOBAL
          language: 'zh_CN',
          language_url: '/static/plugins/tinymce/zh_CN.js',
          skin_url: '/static/plugins/tinymce/skins/lightgray',
          height: 450,
          theme: 'modern',
          toolbar: `styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image  media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat  hr | paste code  link | undo redo | fullscreen `,
          plugins: ` paste importcss image code table advlist fullscreen link media lists textcolor colorpicker hr preview `,
          // CONFIG
          forced_root_block: 'p',
          importcss_append: true,

          // CONFIG: ContentStyle 这块很重要， 在最后呈现的页面也要写入这个基本样式保证前后一致， `table`和`img`的问题基本就靠这个来填坑了
          content_style: `
                            *                         { padding:0; margin:0; }
                            html, body                { height:100%; }
                            img                       { max-width:100%; display:block;height:auto; }
                            a                         { text-decoration: none; }
                            iframe                    { width: 100%; }
                            p                         { line-height:1.6; margin: 0px; }
                            table                     { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
                            .mce-object-iframe        { width:100%; box-sizing:border-box; margin:0; padding:0; }
                            ul,ol                     { list-style-position:inside; }
                          `,

          insert_button_items: 'image link | inserttable',

          // CONFIG: Paste
          paste_retain_style_properties: 'all',
          paste_word_valid_elements: '*[*]',        // word需要它
          paste_data_images: true,                  // 粘贴的同时能把内容里的图片自动上传，非常强力的功能
          paste_convert_word_fake_lists: false,     // 插入word文档需要该属性
          paste_webkit_styles: 'all',
          paste_merge_formats: true,
          nonbreaking_force_tab: false,
          paste_auto_cleanup_on_paste: false,

          // CONFIG: Font
          fontsize_formats: '10px 11px 12px 14px 16px 18px 20px 24px',

          // CONFIG: StyleSelect
          style_formats: [
            {
              title: '首行缩进',
              block: 'p',
              styles: { 'text-indent': '2em' }
            },
            {
              title: '行高',
              items: [
                {title: '1', styles: { 'line-height': '1' }, inline: 'span'},
                {title: '1.5', styles: { 'line-height': '1.5' }, inline: 'span'},
                {title: '2', styles: { 'line-height': '2' }, inline: 'span'},
                {title: '2.5', styles: { 'line-height': '2.5' }, inline: 'span'},
                {title: '3', styles: { 'line-height': '3' }, inline: 'span'}
              ]
            }
          ],

          // FontSelect
          font_formats: `
                        微软雅黑=微软雅黑;
                        宋体=宋体;
                        黑体=黑体;
                        仿宋=仿宋;
                        楷体=楷体;
                        隶书=隶书;
                        幼圆=幼圆;
                        Andale Mono=andale mono,times;
                        Arial=arial, helvetica,
                        sans-serif;
                        Arial Black=arial black, avant garde;
                        Book Antiqua=book antiqua,palatino;
                        Comic Sans MS=comic sans ms,sans-serif;
                        Courier New=courier new,courier;
                        Georgia=georgia,palatino;
                        Helvetica=helvetica;
                        Impact=impact,chicago;
                        Symbol=symbol;
                        Tahoma=tahoma,arial,helvetica,sans-serif;
                        Terminal=terminal,monaco;
                        Times New Roman=times new roman,times;
                        Trebuchet MS=trebuchet ms,geneva;
                        Verdana=verdana,geneva;
                        Webdings=webdings;
                        Wingdings=wingdings,zapf dingbats`,

          // Tab
          tabfocus_elements: ':prev,:next',
          object_resizing: true,

          // Image
          imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions'
        }
      }
    },
    props: {
      id: {
        type: String,
        default: 'tinymce'
      },
      // 初始化值
      value: {
        default: '',
        type: String
      },
      // 实例配置
      config: {
        type: Object,
        default: function () {
          return {
            theme: 'modern'
          }
        }
      },
      // 图片上传路径
      url: {
        default: '',
        type: String
      },
      // 允许的图片格式
      accept: {
        default: 'image/jpeg,image/png,image/jpg',
        type: String
      },
      // 图片大小限制
      maxSize: {
        default: 2097152,
        type: Number
      },
      // 跨域相关
      withCredentials: {
        default: false,
        type: Boolean
      },
      // 是否已保存富文本的值
      isSave: {
        default: true,
        type: Boolean
      },
      // 上传的图片数组
      uploadImg: {
        default: function () {
          return []
        },
        type: Array
      }
    },
    components: {
      Editor
    },
    computed: {
      // 所用的配置项
      rootConfig: function () {
        var that = this
        return {
          // 默认配置
          ...that.DefaultConfig,
          // 图片上传
          images_upload_handler: function (blobInfo, success, failure) {
            if (blobInfo.blob().size > that.maxSize) {
              failure('文件体积过大')
            }
            if (that.accept.indexOf(blobInfo.blob().type) >= 0) {
              uploadPic()
            } else {
              failure('图片格式错误')
            }
            function uploadPic () {
              let formData = new FormData()
              formData.append('file', blobInfo.blob(), blobInfo.filename())
              let config = {headers: {'Content-Type': 'multipart/form-data'}}
              that.$http.post(that.url, formData, config).then(function (res) {
                if (res.status === 200 && res.data.code === 0) {
                  // 成功抛出 'on-upload-success' 钩子
                  that.uploadImg.push(res.data.url)
                  that.$emit('on-upload-success', res.data.url)
                  success(res.data.url)
                } else {
                  that.$emit('on-upload-fail')
                  failure('上传失败: ' + (res.status === 200 ? res.data.code : res.statusText))
                }
              }).catch(function (e) {
                // 失败抛出 'on-upload-fail' 钩子
                that.$emit('on-upload-fail')
                failure('上传失败: ' + e)
              })
            }
          },
          // prop内传入的的config
          ...that.config,
          // 挂载的DOM对象
          selector: `#${that.id}`,
          // 呈现TinyMCE编辑器实例之前执行的回调
          setup: (editor) => {
            // 抛出 'on-ready' 事件钩子
            editor.on(
              'init', () => {
                that.loading = false
                that.$emit('on-ready')
                editor.setContent(that.value)
              }
            )
            // 抛出 'input' 事件钩子，同步value数据
            editor.on(
              'input change undo redo', () => {
                that.$emit('input', editor.getContent())
              }
            )
          }
        }
      }
    },
    methods: {
      // 得到富文本的值，通过this.$refs.[tinymce].getContent()
      getContent: function () {
        return this.tinymceHtml
      },
      // 设置富文本的值，通过this.$refs.[tinymce].setContent()
      setContent: function (content) {
        this.tinymceHtml = content
      }
    },
    beforeDestroy () {
      // 销毁tinymce
      this.$emit('on-destroy')
      tinymce.remove(`#${this.id}`)
    }
  }
</script>
